package com.jd.sunny.java.multithreading.synch;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description:
 * @author:sunny
 * @since:2012-12-12 18:21
 * @version:1.0.0
 */
public class Account {

    /**
     * volatile 貌似没起作用
     */
    private volatile String name;
    private volatile long money;
    private static Lock lock = new ReentrantLock();
    private static Condition condition;

    public Account(String name, long money) {
        this.name = name;
        this.money = money;
        //condition object
        condition = lock.newCondition();
    }

    /**
     *synchronized method
     * @param from
     * @param to
     * @param money
     */
//    public static synchronized void transfer(Account from,Account to, long money){
//        System.out.println(Thread.currentThread() + "from:" + from.getMoney() + "  to:" + to.getMoney() +
//                "all:" + (from.getMoney() + to.getMoney()));
//
//        from.setMoney( from.getMoney() - money);
//        to.setMoney(to.getMoney() + money);
//
//        System.out.println(Thread.currentThread() + "from:" + from.getMoney() + "  to:" + to.getMoney() +
//                "all:" + (from.getMoney() + to.getMoney()));
//    }

    /**
     * use Lock
     * @param from
     * @param to
     * @param money
     */
    public static void transfer(Account from,Account to, long money){
//        System.out.println(Thread.currentThread() + "from:" + from.getMoney() + "  to:" + to.getMoney() +
//                "all:" + (from.getMoney() + to.getMoney()));
        //锁
        lock.lock();
        try{
            //while 条件 等待
            while ((from.getMoney() < money)){
                //put this thread in the condition wait pool 将该线程放到条件的等待集中
                condition.await();
            }
            from.setMoney( from.getMoney() - money);
            to.setMoney(to.getMoney() + money);
            System.out.println(Thread.currentThread() + from.getName() + ":" +from.getMoney() +"   " +  to.getName()
                    + ":" + to.getMoney() + "all:" + (from.getMoney() + to.getMoney()));
            //解锁该条件等待集中的所有线程的阻塞状态，
            condition.signalAll();
            //随机解锁该条件等待集中一个线程的阻塞状态
//            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //解锁，必须
            lock.unlock();
        }
    }

    /**
     * 从其他账户转账到当前账户
     * @param from
     * @param money
     */
    public void transfer(Account from, long money){
        transfer(from,this,money);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getMoney() {
        return money;
    }

    public void setMoney(long money) {
        this.money = money;
    }
}
